Skip to content

Implement cem/ohpcf#223

Open
sthelen-enqs wants to merge 13 commits into
devfrom
implement-cem-ohpcf
Open

Implement cem/ohpcf#223
sthelen-enqs wants to merge 13 commits into
devfrom
implement-cem-ohpcf

Conversation

@sthelen-enqs

Copy link
Copy Markdown
Contributor

No description provided.

@andig

andig commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

OT: I'm wondering how useful OHPCF, especially compared to FLOA, really is in real-live scenarios. How does it help if the heatpump announces 5kW for unknown runtime if your PV only delivers 4kW?

Comment thread usecases/api/cem_ohpcf.go
//
// parameters:
// - start: The start time of the power consumption
SchedulePowerConsumptionProcess(entity spineapi.EntityRemoteInterface, start time.Time, resultCB func(result model.ResultDataType)) (*model.MsgCounterType, error)

@andig andig Jun 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hard-codes SchedulePowerConsumptionProcess to using model.NewAbsoluteOrRelativeTimeTypeFromTime(start) which doesn't work on Vaillant which only accepts durations. From the AbsoluteOrRelativeTimeType — EEBus_SPINE_TS_CommonDataTypes.xsd, lines 51–53:

<xs:simpleType name="AbsoluteOrRelativeTimeType">
    <xs:union memberTypes="xs:duration xs:dateTime"/>
</xs:simpleType>

I'd be happy to provide a PR. Options:

  • have both time and duration variants of the function
  • make start a variadic option (WithTime vs WithDuration)
  • simplify have the actual model type passed in (via interface or any)

Which one would you prefer?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems passing the start time as *model.AbsoluteOrRelativeTimeType is the absolute easiest way of doing this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took another look:

┌──────────────────────────────────────┬─────────────────────────────────┬───────────────────────────────┬────────────────────────────────────────────────────────┐
│               Use case               │              Field              │        Encoding chosen        │                      constructor                       │
├──────────────────────────────────────┼─────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────────────────┤
│ cs/lpc/public.go:81                  │ LoadControl limit EndTime       │ relative                      │ ...FromDuration(limit.Duration)                        │
├──────────────────────────────────────┼─────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────────────────┤
│ cs/lpp/public.go:83                  │ LoadControl limit EndTime       │ relative                      │ ...FromDuration(limit.Duration)                        │
├──────────────────────────────────────┼─────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────────────────┤
│ usecases/internal/loadcontrol.go:162 │ LoadControl limit EndTime       │ relative                      │ ...FromDuration(limit.Duration)                        │
├──────────────────────────────────────┼─────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────────────────┤
│ cem/cevc/public_scen2.go:111-130     │ TimeSeries Start/End            │ relative (incl. literal       │ ...FromDuration /                                      │
│                                      │                                 │ "PT0S")                       │ NewAbsoluteOrRelativeTimeType("PT0S")                  │
├──────────────────────────────────────┼─────────────────────────────────┼───────────────────────────────┼────────────────────────────────────────────────────────┤
│ cem/ohpcf/public.go:308              │ PowerSequence Schedule          │ absolute                      │ ...FromTime(start) ← outlier                           │
│                                      │ StartTime                       │                               │                                                        │
└──────────────────────────────────────┴─────────────────────────────────┴───────────────────────────────┴────────────────────────────────────────────────────────┘

Rest of the library is using duration. This is the only place where actual time seems to be used. So the idiomatic fix- without adding additional flexibility would be changing start into startIn as time.Duration.

wdyt?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should settle it:

3.1.8.2 Rules regarding the usage of time-related information
All time-related information within this Use Case SHALL be presented as relative times. This means
absolute times SHALL NOT be used. All start- and end-times SHALL be interpreted as relative to the
time the message was transmitted.

@andig

andig commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

OT: I'm wondering how useful OHPCF, especially compared to FLOA, really is in real-live scenarios. How does it help if the heatpump announces 5kW for unknown runtime if your PV only delivers 4kW?

The FLOA spec hasn‘t even been released, much less implemented…

@andig

andig commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

@sthelen-enqs fwiw I can confirm this works against Vaillant heatpump with the proposed changes. It would be great to get both merged! If you need anything specifically tested pls let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants